/* Copyright 2012 Dustin Mitchell <dmmitche [at] gmail [dot] com>
 *
 * Licensed under the GPLv3.  See included LICENSE.txt for full details.
 */

#ifndef __SENSOR__
#define __SENSOR__

#include <stdint.h>

#include "uart.h"

enum sensor_type
{
  SENSOR_GPS,
  SENSOR_WAKE_UP
};



struct gps_reading
{
  enum sensor_type type;
  int value;
};

struct wake_up_reading
{
  enum sensor_type type;
  uint64_t n_expirations;
};

union sensor_reading
{
  enum sensor_type type;
  struct gps_reading gps;
  struct wake_up_reading wake_up;
};



struct gps_sensor_def
{
  enum sensor_type type;
  struct uart_hw_module *hw_uart;
  int baud;
};

struct wake_up_sensor_def
{
  enum sensor_type type;
  int period_ms;
};

union sensor_def
{
  enum sensor_type type;
  struct gps_sensor_def gps;
  struct wake_up_sensor_def wake_up;
};



union sensor;

struct sensor_ops
{
  /* Returns -1 on error, 0 on no reading available, 1 on reading available */
  int (*read) (union sensor *, union sensor_reading *);
  int (*get_selectable) (union sensor *);
};

struct sensor_base
{
  enum sensor_type type;
  struct sensor_ops ops;
};

struct gps_sensor
{
  struct sensor_base base;
  struct uart hw_uart;
};

struct wake_up_sensor
{
  struct sensor_base base;
  int clock_fd;
  uint64_t n_expirations;
};

union sensor
{
  struct sensor_base sensor;
  struct gps_sensor gps;
  struct wake_up_sensor wake_up;
};



int sensor_base_create (struct sensor_base *base, enum sensor_type type,
                        struct sensor_ops *ops);



int sensor_create (union sensor *sensor, union sensor_def *def);

void sensor_destroy (union sensor *sensor);

int sensor_read (union sensor *sensor, union sensor_reading *reading);

int sensor_get_selectable (union sensor *sensor);

#define SENSOR(p) ((struct sensor *)(p))

#endif /* __SENSOR__ */
